package com.itheima.dubbo.mysql.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.dubbo.config.annotation.Service;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itheima.commons.pojo.domain.UserInfo;
import com.itheima.commons.pojo.entity.Distribution;
import com.itheima.commons.vo.backstage.DistributionVo;
import com.itheima.commons.vo.backstage.SummaryVo;
import com.itheima.commons.vo.backstage.UsersVo;
import com.itheima.dubbo.interfaces.UserInfoApi;
import com.itheima.dubbo.mysql.mapper.LogMapper;
import com.itheima.dubbo.mysql.mapper.UserInfoMapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author yaohu
 * @date 2021/12/5
 * @Version 1.0
 * @describe
 */
@Service
public class UserInfoApiImpl implements UserInfoApi {

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Autowired
    private LogMapper logMapper;

    @Override
    public void addUserInfo(UserInfo userInfo) {
        userInfoMapper.insert(userInfo);
    }

    @Override
    public void updateLogo(Long uid, String pictureUrl) {
        userInfoMapper.update(UserInfo.builder().logo(pictureUrl).build(),
                Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserId, uid));
    }

    @Override
    public UserInfo findUserInfoByUserId(Long userId) {
        return userInfoMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getUserId, userId));
    }

    /**
     * @param userInfo 用户筛选的信息
     * @param userIds
     * @return
     */
    @Override
    public Map<Long, UserInfo> findUserInfoByUserIds(UserInfo userInfo, List<Long> userIds) {
        List<UserInfo> userInfos = userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class)
                        .in(UserInfo::getUserId, userIds)
//                .eq(ObjectUtil.isNotNull(userInfo.getSex()), UserInfo::getSex, userInfo.getSex())
//                .eq(ObjectUtil.isNotNull(userInfo.getCity()), UserInfo::getCity, userInfo.getCity())
//                .eq(ObjectUtil.isNotNull(userInfo.getAge()), UserInfo::getAge, userInfo.getAge())
//                .eq(ObjectUtil.isNotNull(userInfo.getEdu()), UserInfo::getEdu, userInfo.getEdu())
                        .like(ObjectUtil.isNotNull(userInfo.getNickName()), UserInfo::getNickName, userInfo.getNickName())
        );
        return CollUtil.fieldValueMap(userInfos, "userId");
    }

    @Override
    public Map<Long, UserInfo> findUserInfoByUserIds(List<Long> userIds) {
        List<UserInfo> userInfos = userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class)
                .in(UserInfo::getUserId, userIds));
        return CollUtil.fieldValueMap(userInfos, "userId");
    }

    //根据评论人id查询评论人昵称
    @Override
    public String findNickNameByUserId(Long userId) {
        UserInfo userInfo = userInfoMapper.selectOne(Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getUserId, userId));
        String nickName = userInfo.getNickName();
        return nickName;
    }

    @Override
    public DistributionVo distribution(Long startTime, Long endTime) {
        Date date = new Date(startTime);
        System.out.println("date = " + date);
        List<Distribution> industryTopTenList = userInfoMapper.findIndustryTopTen(new Date(startTime), new Date(endTime));
        List<Distribution> ageDistribution = userInfoMapper.findAgeDistribution(new Date(startTime), new Date(endTime));
        List<Distribution> genderDistribution = userInfoMapper.findgenderDistribution(new Date(startTime), new Date(endTime));
        List<Distribution> localdistributions = userInfoMapper.findlocalDistribution(new Date(startTime), new Date(endTime));
        List<Distribution> localTotal = userInfoMapper.findlocalTotal(new Date(startTime), new Date(endTime));

        DistributionVo distributionVo = new DistributionVo();
        distributionVo.setIndustryDistribution(industryTopTenList);
        distributionVo.setAgeDistribution(ageDistribution);
        distributionVo.setGenderDistribution(genderDistribution);
        distributionVo.setLocalDistribution(localdistributions);
        distributionVo.setLocalTotal(localTotal);
        return distributionVo;
    }

    @Override
    public UsersVo users(Integer type, Long startTime, Long endTime) {
        //1.把所选时间段切割成"yyyy-MM-dd"格式，并保存进List集合中
        if (type == 103) {
            endTime = endTime + 24 * 3600 * 1000;
        }
        List<String> thisYearString = splitDateList(new Date(startTime), new Date(endTime));
        //2.获取所选时间的区间的一年前的时间戳
        Calendar c = Calendar.getInstance();
        c.setTime(new Date(startTime));
        c.add(Calendar.YEAR, -1);
        //获取起始时间一年前的时间戳
        Long lastYearStartTime = c.getTime().getTime();
        c.setTime(new Date(endTime));
        c.add(Calendar.YEAR, -1);
        //获取结束时间一年前的时间戳
        Long lastYearEndTime = c.getTime().getTime();
        //3.把一年前的时间段切割成"yyyy-MM-dd"格式，并保存进List集合中
        List<String> lastYearString = splitDateList(new Date(lastYearStartTime), new Date(lastYearEndTime));
        UsersVo usersVo = new UsersVo();
        switch (type) {
            case 101:
                List<Distribution> thisYearNewUsers = new ArrayList<>();
                List<Distribution> lastYearNewUsers = new ArrayList<>();
                for (int i = 0; i < thisYearString.size(); i++) {
                    Distribution thisDistribution = userInfoMapper.findNewUser(thisYearString.get(i));
                    Distribution lastDistribution = userInfoMapper.findNewUser(lastYearString.get(i));
                    thisYearNewUsers.add(thisDistribution);
                    lastYearNewUsers.add(lastDistribution);
                }
                usersVo.setThisYear(thisYearNewUsers);
                usersVo.setLastYear(lastYearNewUsers);
                break;
            case 102:
                List<Distribution> thisYearActiveUsers = new ArrayList<>();
                List<Distribution> lastYearActiveUsers = new ArrayList<>();
                for (int i = 0; i < thisYearString.size(); i++) {
                    Distribution thisDistribution = logMapper.findDayActiveUser(thisYearString.get(i));
                    Distribution lastDistribution = logMapper.findDayActiveUser(lastYearString.get(i));
                    thisYearActiveUsers.add(thisDistribution);
                    lastYearActiveUsers.add(lastDistribution);
                }
                usersVo.setThisYear(thisYearActiveUsers);
                usersVo.setLastYear(lastYearActiveUsers);
                break;
            case 103:
                List<Distribution> thisYearRetentionUsers = new ArrayList<>();
                List<Distribution> lastYearRetentionUsers = new ArrayList<>();
                for (int i = 0; i < thisYearString.size()-1; i++) {
                    List<Long> todayLoginUserIds = logMapper.findDayRetentionUser(thisYearString.get(i));
                    List<Long> tomorrowLoginUserIds = logMapper.findDayRetentionUser(thisYearString.get(i + 1));
                    Collection<Long> thisIntersection = CollUtil.intersection(todayLoginUserIds, tomorrowLoginUserIds);

                    List<Long> lastTodayLoginUserIds = logMapper.findDayRetentionUser(lastYearString.get(i));
                    List<Long> lastTomorrowLoginUserIds = logMapper.findDayRetentionUser(lastYearString.get(i + 1));
                    Collection<Long> lastIntersection = CollUtil.intersection(lastTodayLoginUserIds, lastTomorrowLoginUserIds);
                    Long thisRetention = 0L;
                    if (todayLoginUserIds.size() != 0) {
                        thisRetention = Convert.toLong((thisIntersection.size() * 100) / todayLoginUserIds.size());
                    }
                    Long lastRetention = 0L;
                    if (lastTodayLoginUserIds.size() != 0) {
                        lastRetention = Convert.toLong((lastIntersection.size() * 100) / lastTodayLoginUserIds.size());
                    }
                    Distribution thisDistribution = new Distribution();
                    Distribution lastDistribution = new Distribution();
                    thisDistribution.setTitle(thisYearString.get(i));
                    thisDistribution.setAmount(thisRetention);
                    lastDistribution.setTitle(lastYearString.get(i));
                    lastDistribution.setAmount(lastRetention);
                    thisYearRetentionUsers.add(thisDistribution);
                    lastYearRetentionUsers.add(lastDistribution);
                }
                usersVo.setThisYear(thisYearRetentionUsers);
                usersVo.setLastYear(lastYearRetentionUsers);
                break;
        }
        return usersVo;
    }

    @Override
    public SummaryVo summary() {
        SummaryVo summaryVo = new SummaryVo();
        //累积注册用户
        Long cumulativeUsers = userInfoMapper.findCumulativeUsers();
        summaryVo.setCumulativeUsers(cumulativeUsers);
        //过去7天活跃用户
        Date nowTime = new Date(System.currentTimeMillis());
        Date passWeekTime = new Date(System.currentTimeMillis()-7*24*3600*1000L);
        Long activePassWeek = logMapper.findActivePassWeek(passWeekTime,nowTime);
        summaryVo.setActivePassWeek(activePassWeek);
        //过去30天活跃用户
        Date passMonthTime = new Date(System.currentTimeMillis()-30*24*3600*1000L);
        Long activePassMonth = logMapper.findActivePassWeek(passMonthTime,nowTime);
        summaryVo.setActivePassMonth(activePassMonth);
        //今日新增人数
        Long newUsersToday = userInfoMapper.findNewUsersToday(dateFormat.format(nowTime));
        summaryVo.setNewUsersToday(newUsersToday);
        //今日新增环比昨日新增的增长率
        Long newUsersYestoday = userInfoMapper.findNewUsersToday(dateFormat.format(new Date(System.currentTimeMillis() - 24 * 3600 * 1000L)));
        Long newUsersTodayRate = 100L;
        if (newUsersYestoday != 0) {
            newUsersTodayRate = ((newUsersToday - newUsersYestoday) * 100) / newUsersYestoday;
        }
        summaryVo.setNewUsersTodayRate(newUsersTodayRate);
        //今日登录次数
        Long loginTimesToday = logMapper.findLoginTimesToday(dateFormat.format(nowTime));
        summaryVo.setLoginTimesToday(loginTimesToday);
        //今日登录次数环比昨日登录次数的增长率
        Long loginTimesYestoday = logMapper.findLoginTimesToday(dateFormat.format(new Date(System.currentTimeMillis() - 24 * 3600 * 1000L)));
        Long loginTimesTodayRate = 100L;
        if (loginTimesYestoday != 0) {
            loginTimesTodayRate = ((loginTimesToday - loginTimesYestoday) * 100) / loginTimesYestoday;
        }
        summaryVo.setLoginTimesTodayRate(loginTimesTodayRate);
        //今日活跃用户数
        Long activeUsersToday = logMapper.findActiveUsersToday(dateFormat.format(nowTime));
        summaryVo.setActiveUsersToday(activeUsersToday);
        //今日活跃用户数环比昨日活跃用户数的增长率
        Long activeUsersYestoday = logMapper.findActiveUsersToday(dateFormat.format(new Date(System.currentTimeMillis() - 24 * 3600 * 1000L)));
        Long activeUsersTodayRate = 100L;
        if (activeUsersYestoday != 0) {
            activeUsersTodayRate = ((activeUsersToday - activeUsersYestoday) * 100) / activeUsersYestoday;
        }
        summaryVo.setActiveUsersTodayRate(activeUsersTodayRate);
        //过去7天是平均日使用时长  该功能不实现  默认为0
        summaryVo.setUseTimePassWeek(0L);
        summaryVo.setActiveUsersYesterday(activeUsersYestoday);
        Long activeUsersBeforeYestoday = logMapper.findActiveUsersToday(dateFormat.format(new Date(System.currentTimeMillis() - 48 * 3600 * 1000L)));
        Long activeUsersYesterdayRate = 100L;
        if (activeUsersBeforeYestoday != 0) {
            activeUsersYesterdayRate = ((activeUsersYestoday - activeUsersBeforeYestoday) * 100) / activeUsersBeforeYestoday;
        }
        summaryVo.setActiveUsersYesterdayRate(activeUsersYesterdayRate);

        return summaryVo;
    }

    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");

    public static List<String> splitDateList(Date startDate, Date endDate) {
        List<String> listDate = new ArrayList<>();
        try {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(startDate);
            while (calendar.getTime().before(endDate) || calendar.getTime().equals(endDate)) {
                listDate.add(dateFormat.format(calendar.getTime()));
                calendar.add(Calendar.DAY_OF_MONTH, 1);
            }
            return listDate;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return listDate;
    }

    /**
     * 统计用户数
     *
     * @return
     */
    @Override
    public Integer queryUserInfoCount() {

        Integer count = userInfoMapper.selectCount(null);
        return count;
    }

    @Override
    public List<UserInfo> findUserByUserIds(List<Long> userIds) {
       return userInfoMapper.selectList(Wrappers.lambdaQuery(UserInfo.class)
                .in(UserInfo::getUserId,userIds));
    }
}
